package gui.customControl;

import gui.util.IconFactory;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.ToolTipManager;

import data.Data.PlayerState;
import data.Player;
import data.Position;

public class PitchCell extends JButton {

	private static final long serialVersionUID = 1L;

	private Color highlight;

	private List<Color> pathHighlight = new ArrayList<Color>();

	// /**
	// * Debug - color for highlighting.
	// */
	// private Color highlightedColor = null;

	private BufferedImage icon = null;

	boolean isBall;

	Player player;

	private final Position pos;

	public PitchCell(final int i, final int j) {
		super();
		this.pos = new Position(i, j);
		highlight = null;
		setData(null, false);
		ToolTipManager.sharedInstance().registerComponent(this);
		ToolTipManager.sharedInstance().setInitialDelay(0);
		ToolTipManager.sharedInstance().setReshowDelay(0);
	}

	/**
	 * When Clicking on players'cell it would show complete information of
	 * player.Depend on their Tuple. IT would show if the player is
	 * Blocker,Thrower,.. - Which Team is belong - Its Race- Has ball or not -
	 * Etc
	 */
	void changeToolTipText() {
		final String newLine = "<br>";
		final String startMessage = "<html>";
		final String endMessage = "</html>";

		String message = null;

		if (isBall == true && player == null) {
			message = startMessage + "The ball" + endMessage;
		} else if (player != null) {
			message = startMessage + "<b>" + player.name() + "</b>" + newLine;
			if (player.hasBall() == true) {
				message += "Player has ball!" + newLine;
			}

			// Race:
			message += "Race: " + player.race().toString() + "." + newLine;

			// Role:
			message += "Role: " + player.role().toString() + "." + newLine;

			// State:
			if (player.state() != PlayerState.IN_PLAY) {
				message += "Player is " + player.state().toString() + "." + newLine;
			}

			// Has played or not
			if (player.hasActed()) {
				message += "Player has acted this turn." + newLine;
			}

			// Stats
			message += "<b>Current movement points: " + player.currentMA() + "</b>" + newLine;
			message += "Player's Agility is  " + player.AG() + "." + newLine;
			message += "Player's Movement Allowance is  " + player.MA() + "." + newLine;
			message += "Player's Strength is  " + player.ST() + "." + newLine;
			message += "Player's Armour Value is  " + player.AV() + "." + newLine;
			message += "Player's Experience is  " + player.XP() + "." + newLine;
			message += "Player's Level is  " + player.level() + "." + newLine;

			if (player.skills().size() > 0) {
				message += "Player's skills are " + player.skills() + "." + newLine;
			}

			// End message
			message += endMessage;
		}

		setToolTipText(message);
	}

	public Player getPlayer() {
		return player;
	}

	/**
	 * Draws the button image
	 */
	@Override
	protected void paintComponent(final Graphics g) {
		final Graphics2D g2d = (Graphics2D) g;

		// Refresh icon
		if (icon == null || icon.getWidth() != getWidth() || icon.getHeight() != getHeight()) {
			setData(player, isBall);
		}

		if (icon != null) {
			g2d.drawImage(icon, 0, 0, null);
		}

		if (pathHighlight.size() > 0) {
			int size = Math.min(getWidth() / 3, getHeight() / 3);

			for (int i = 0; i < pathHighlight.size(); i++) {
				Color c = pathHighlight.get(i);
				g2d.setColor(c);
				g2d.fillOval(getWidth() / 2 - size / 2 + 3 * i, getHeight() / 2 - size / 2 + 3 * i, size, size);
			}
		}

		if (highlight != null) {
			g2d.setColor(highlight);
			g2d.fillRect(0, 0, getWidth(), getHeight());
		}
	}

	public Position pos() {
		return pos;
	}

	/**
	 * Updates the button internal data and rebuilds the image of the button.
	 * 
	 * @param player
	 * @param isBall
	 */
	public void setData(final Player player, final boolean isBall) {
		// First, set actual data
		this.player = player;
		this.isBall = isBall;

		update();
	}

	public void update() {
		// Then, regenerate the button image.
		icon = IconFactory.instance().getPitchIcon(player, isBall, pos, this);

		// set tooltip text
		changeToolTipText();

		// Refresh component...
		this.repaint();
	}

	/**
	 * Setter for the "pathHighlight" property.
	 * 
	 * @param highlight
	 *            the highlight to set
	 * 
	 * @author Tomasz Dąbrowski
	 */
	public void setPathHighlight(final Color highlight) {
		if (highlight != null) {
			this.pathHighlight.add(new Color(highlight.getRed(), highlight.getGreen(), highlight.getBlue(), 140));
		} else {
			this.pathHighlight.clear();
		}
		this.repaint();
	}

	/**
	 * Setter for the "highlight" property.
	 * 
	 * @param highlight
	 *            the highlight to set
	 * 
	 * @author Tomasz Dąbrowski
	 */
	public void setHighlight(final Color highlight) {
		if (highlight != null) {
			this.highlight = new Color(highlight.getRed(), highlight.getGreen(), highlight.getBlue(), 80);
		} else {
			this.highlight = null;
		}
		this.repaint();
	}

	public void updateHighlight() {
		// Get the highlight color if any
		highlight = IconFactory.instance().getHighlight(pos);

		// Refresh component visual
		this.repaint();
	}

	public int X() {
		return pos.x();
	}

	public int Y() {
		return pos.y();
	}
}